一個Http 應用程式可以看做一群endpoint(端點)的集合
透過路由可以將URL配對至對應的對點
讓外部的使用者只要知道URL 就能呼叫需要的端點
Route會把url如何對應endpoint存在路由表中
當request 進來後會根據路由表找尋最佳的的endpoint
在pipeline 中使用app.UseRouting();
可以明確
載入路由中介軟體
明確的意思是,如果是WebHost
的話,預設就會啟用Routing
但是有時候為了要讓自訂中介軟體在UseRouting()
前/後 執行
這時就會明確指定UsingRouting的位置
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.UseRouting();
app.Use(async (context, next) =>
{
// do something
await next();
});
app.MapControllers();
await app.RunAsync();
這邊假設我有個服務可以根據ISBN取得書籍資訊
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.UseRouting();
app.MapGet("/books/{isbn}",
(string isbn) =>
{
return isbn switch
{
"1234567890" => Results.Ok(new Book("1234567890", "The Hitchhiker's Guide to the Galaxy")),
"0987654321" => Results.Ok(new Book("0987654321", "The Restaurant at the End of the Universe")),
_ => Results.NotFound()
};
});
app.MapControllers();
await app.RunAsync();
public record Book(string ISBN, string Name);
當我使用HttpGet呼叫/books/1234567890
可以拿到對應的書籍
其中 /books/{isbn}
為這個取得書籍服務endpoint 的路由範本
另外路由範本也可以這樣設定/Homework/{name}.{extension?}
當使用/Homework/SSN1-888.mp4
或/Homework/SSN1-888
都可以匹配到相同的端點取得檔案
另外也可以使用萬用字元,但只能用在最後一個參數,代表匹配多個路由/Homework/{*name}
可以用/Homework/SCD/SSN1/888.mp4
/Homework/Taipei/Hot/n0847.wav
走到相同端點
一個Routing Pattern
可以被拆成RoutePatternPart
物件來表示
RoutePatternPart.cs
public abstract class RoutePatternPart
{
private protected RoutePatternPart(RoutePatternPartKind partKind)
{
PartKind = partKind;
}
public RoutePatternPartKind PartKind { get; }
public bool IsLiteral => PartKind == RoutePatternPartKind.Literal;
public bool IsParameter => PartKind == RoutePatternPartKind.Parameter;
public bool IsSeparator => PartKind == RoutePatternPartKind.Separator;
internal abstract string DebuggerToString();
}
RoutePatternPart.cs
共有三種類型
由enum RoutePatternPartKind
表示RoutePatternPartKind.cs
public class RoutePatternPartKind{
Literal,
Parameter,
Separator
}
/books/{isbn}
中的books
/books/{isbn}
的 {isbn}
跟 /Homework/{*name}
的 {*name}
都是這個類型/Homework/{name}.{extension?}
中間用分隔符號分開得其中比較特別的子類別是 RoutePatternParameterPart
也就是參數型態的
public sealed class RoutePatternParameterPart : RoutePatternPart
{
public IReadOnlyList<RoutePatternParameterPolicyReference> ParameterPolicies { get; }
public bool EncodeSlashes { get; }
public object? Default { get; }
public bool IsCatchAll => ParameterKind == RoutePatternParameterKind.CatchAll;
public bool IsOptional => ParameterKind == RoutePatternParameterKind.Optional;
public RoutePatternParameterKind ParameterKind { get; }
public string Name { get; }
internal override string DebuggerToString()
}
/
會被urlencoding成 %2f
book/{isbn = 12}
,12會放這book/{isbn = 12}
,Name 為isbn
ParameterKind.cs
public enum RoutePatternParameterKind
{
Standard,
Optional,
CatchAll,
}
有預設值(book/{isbn = 12}
)的為Optional
,萬用字元則為CatchAll
我們前面有提到路由表
,.Net Core 的路由表本身就是RoutePattern
物件的集合
RoutePattern.cs
public sealed class RoutePattern
{
public IReadOnlyDictionary<string, object?> Defaults { get; }
public IReadOnlyDictionary<string, IReadOnlyList<RoutePatternParameterPolicyReference>> ParameterPolicies { get; }
public IReadOnlyDictionary<string, object?> RequiredValues { get; }
public decimal InboundPrecedence { get; }
public decimal OutboundPrecedence { get; }
public string? RawText { get; }
public IReadOnlyList<RoutePatternParameterPart> Parameters { get; }
public IReadOnlyList<RoutePatternPathSegment> PathSegments { get; }
}
/
中間的的區段,他是由IReadOnlyList<RoutePatternPart>
所組成"book/{isbn = 12}"
不管是針對解析路由,或是產出完整的URL,都會要從路由表找符合的pattern
有沒有那麼一種可能,你要解析的路由剛好滿足兩個或以上的Pattern(有,而且滿常遇到的QQ)
當出現這種形況的時候InboundPrecedence
表示解析時的加權OutboundPrecedence
表示產生URL的加權
加權越高,優先度越高